import json
import aiohttp
import asyncio
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select
from db.models import PetType, Pet, RaceGroup, RaceGroupPetBanHide, RaceGroupPetTypeHide, Suit
from db.mysql_part import get_mysql_session, get_mysql_engine
from db.mongo_part import xibie_mongo
from scripts.base_data import bans, default_group_config
from db.models import Base

async def load_type_data():
    sp_types = [8, 221, 223, 224, 225, 226]
    pre_type = PetType()
    pre_type.pet_type_id = 222
    pre_type.pet_type_name = '混沌'
    async with get_mysql_session() as session:
        await session.merge(pre_type)

    async with aiohttp.ClientSession() as session:
        async with session.get('https://seerh5.61.com/version/version.json') as resp:
            data = await resp.json()
            skill_types_target = data['files']['resource']['config']['xml']['skillTypes.json']
            async with session.get(f'https://seerh5.61.com/resource/config/xml/{skill_types_target}') as resp:
                skill_types = await resp.json()
                skill_types = skill_types['root']['item']
                
                for tp in skill_types:
                    pet_type = PetType()
                    if sp_types.__contains__(tp['id']):
                        continue
                    
                    pet_type.pet_type_id = tp['id']
                    pet_type.pet_type_name = tp['cn']
                    
                    if 'att' in tp:
                        pet_type.sub_type1 = 8 if sp_types.__contains__(int(tp['att'].split(' ')[0])) else int(tp['att'].split(' ')[0])
                        pet_type.sub_type2 = 8 if sp_types.__contains__(int(tp['att'].split(' ')[1])) else int(tp['att'].split(' ')[1])
                    
                    async with get_mysql_session() as session:
                        await session.merge(pet_type)
    print("属系数据导入完毕")


async def load_pet_data_base():
    sp_types = [8, 221, 223, 224, 225, 226]
    
    async with aiohttp.ClientSession() as session:
        async with session.get('https://seerh5.61.com/version/version.json') as resp:
            data = await resp.json()
            special_heads = data['files']['resource']['assets']['pet']['head']
            pets_data_target = data['files']['resource']['config']['xml']['monsters.json']
            
            async with session.get(f'https://seerh5.61.com/resource/config/xml/{pets_data_target}') as resp:
                data = await resp.json()
                pets_data = data['Monsters']['Monster']
                
                async def insert_pet_batch(pets: list[Pet]):
                    async with get_mysql_session() as session:
                        for pet in pets:
                            await session.merge(pet)
                            pet.pet_origin_id = pet.pet_id
                            await session.merge(pet)
                tasks = []
                pets: list[Pet] = []
                for item in pets_data:
                    if item['ID'] > 5000:
                        continue
                    
                    pet = Pet()
                    pet.pet_id = item['ID']
                    pet.pet_name = item['DefName']
                    if sp_types.__contains__(item['Type']):
                        pet.pet_type = 8
                    else:
                        pet.pet_type = item['Type']
                    if f"{pet.pet_id}.png" in special_heads:
                        pet.head_hs = f"{special_heads[f'{pet.pet_id}.png']}"
                    pets.append(pet)
                    if len(pets) >= 1000:
                        tasks.append(asyncio.create_task(insert_pet_batch(pets)))
                        pets = []
                
                if len(pets) > 0:
                    tasks.append(asyncio.create_task(insert_pet_batch(pets)))
                
                await asyncio.gather(*tasks)

                print("精灵基础数据导入完毕")
                    

                
            
async def load_pet_data_extra():
    async with aiohttp.ClientSession() as session:
        async with session.get('https://seerh5.61.com/version/version.json') as resp:
            data = await resp.json()
            icon_data_target = data['files']['resource']['config']['xml']['effectIcon.json']
            sp_moves_data_target = data['files']['resource']['config']['xml']['sp_hide_moves.json']
            
            async def get_icon_data():
                async with session.get(f'https://seerh5.61.com/resource/config/xml/{icon_data_target}') as resp:
                    data = await resp.json()
                    return data['root']['effect']
            
            async def get_sp_moves_data():
                async with session.get(f'https://seerh5.61.com/resource/config/xml/{sp_moves_data_target}') as resp:
                    data = await resp.json()
                    return data['config']['SpMoves']
                
            tasks = [get_icon_data(), get_sp_moves_data()]
            icon_data, sp_moves_data = await asyncio.gather(*tasks)
            
            
            async def insert_pet_extra_icon(icons: list):
                async with get_mysql_session() as session:
                    for icon in icons:
                        pet_id = icon['petId']
                        pet = await session.get(Pet, pet_id)
                        if pet is None:
                            continue
                        if type(pet_id) == str:
                            continue
                            
                        pet_extra = Pet(
                            pet_id=pet_id * 100 + 1,
                            pet_origin_id = pet_id,
                            pet_name=pet.pet_name + '（魂印强化）',
                            pet_type=pet.pet_type,
                            head_hs=pet.head_hs,
                            ex_icon=icon['effectId'],
                            ex_icon_text=icon['come']
                        )
                        await session.merge(pet_extra)
                    
            async def insert_pet_extra_skill(skills: list):
                async with get_mysql_session() as session:
                    for skill in skills:
                        pet_id = skill['monster']
                        pet = await session.get(Pet, pet_id)
                        if pet is None:
                            continue
                        pet_extra = Pet(
                            pet_id=pet_id * 100 + 2,
                            pet_origin_id = pet_id,
                            pet_name=pet.pet_name + '（额外技能）',
                            pet_type=pet.pet_type,
                            head_hs=pet.head_hs,
                            ex_skill=skill['moves'],
                            ex_skill_text=skill['movesname']
                        )
                        
                        await session.merge(pet_extra)
                        
            ex_icons = []
            for icon in icon_data:
                if 'come' in icon:
                    if icon['come'].__contains__('伙伴效果'):
                        ex_icons.append(icon)
                    if icon['come'].__contains__('羁绊'):
                        ex_icons.append(icon)
                    if icon['come'].__contains__('神谕'):
                        ex_icons.append(icon)
                    if icon['come'].__contains__('元素觉醒'):
                        ex_icons.append(icon)
                    if icon['come'].__contains__('特性升级'):
                        ex_icons.append(icon)
                    if icon['come'].__contains__('魂印进化'):
                        ex_icons.append(icon)
                    if icon['come'].__contains__('特训'):
                        ex_icons.append(icon)
            # print(ex_icons)

            tasks = [insert_pet_extra_icon(ex_icons), insert_pet_extra_skill(sp_moves_data)]
            await asyncio.gather(*tasks)
            
            print("精灵额外数据导入完毕")
            
async def init_mongo_collection():
    target_collections = ['game_logs', 'race_groups']
    collections = await xibie_mongo.list_collection_names()
    for collection in target_collections:
        if collection not in collections:
            await xibie_mongo.create_collection(collection)
            
async def insert_default_group_mongo():
    for index, config in enumerate(default_group_config['limit_config']):
        config['limit_id'] = index + 1
    
    group_id = default_group_config['group_id']
    if await xibie_mongo.race_groups.find_one({'group_id': group_id}):
        await xibie_mongo.race_groups.update_one({'group_id': group_id}, {'$set': default_group_config})
    else:
        await xibie_mongo.race_groups.insert_one(default_group_config)
    
async def insert_default_group_mysql():
    group_id = 1
    group_name = "默认组"
    async with get_mysql_session() as session:
        await session.merge(RaceGroup(group_id=group_id, group_name=group_name))
        for pet_id in bans:
            await session.merge(RaceGroupPetBanHide(group_id=group_id, pet_id=pet_id, is_banned=1))

async def init_mysql_table():
    async with get_mysql_engine().connect() as conn:
        await conn.run_sync(Base.metadata.drop_all)
        await conn.run_sync(Base.metadata.create_all)

async def init_mysql_data():    
    await load_type_data()
    await load_pet_data_base()
    await load_pet_data_extra()
    await insert_default_group_mysql()

async def init_mongo_data():
    await init_mongo_collection()
    await insert_default_group_mongo()

async def pet_ex_mark():
    async with get_mysql_session() as session:
        pets = await session.execute(select(Pet).where(Pet.pet_id < 500000, Pet.pet_id > 5000))
        for pet in pets.scalars():
            origin_pet = await session.get(Pet, pet.pet_origin_id)
            origin_pet.ex_mark = 1
            await session.merge(origin_pet)
        await session.commit()